package com.zxl.designpattern.behavioral.command;

/**
 * 遥控器类
 * 作为调用者，持有多个命令对象，并可以调用它们的execute()方法
 */
public class RemoteControl {

    // 开命令数组
    private final Command[] onCommands;
    // 关命令数组
    private final Command[] offCommands;
    // 撤销命令
    private Command undoCommand;
    // 初始化命令池大小
    private static final int SLOTS = 5;

    /**
     * 构造函数，初始化遥控器
     */
    public RemoteControl() {
        onCommands = new Command[SLOTS];
        offCommands = new Command[SLOTS];

        // 初始化所有插槽为空命令
        Command noCommand = new NoCommand();
        for (int i = 0; i < SLOTS; i++) {
            onCommands[i] = noCommand;
            offCommands[i] = noCommand;
        }
        undoCommand = noCommand;
    }

    /**
     * 设置插槽的命令
     * @param slot 插槽编号
     * @param onCommand 开命令
     * @param offCommand 关命令
     */
    public void setCommand(int slot, Command onCommand, Command offCommand) {
        onCommands[slot] = onCommand;
        offCommands[slot] = offCommand;
    }

    /**
     * 按下开按钮
     * @param slot 插槽编号
     */
    public void onButtonWasPushed(int slot) {
        // 开了之后，命令就变成可关的了
        onCommands[slot].execute();
        undoCommand = onCommands[slot];
    }

    /**
     * 按下关按钮
     * @param slot 插槽编号
     */
    public void offButtonWasPushed(int slot) {
        // 关了之后，命令就变成可开的了
        offCommands[slot].execute();
        undoCommand = offCommands[slot];
    }

    /**
     * 按下撤销按钮
     */
    public void undoButtonWasPushed() {
        undoCommand.undo();
    }

    @Override
    public String toString() {
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("\n------ 遥控器 ------\n");
        for (int i = 0; i < onCommands.length; i++) {
            stringBuilder.append("[插槽 ").append(i).append("] ")
                    .append(onCommands[i].getCommandName())
                    .append("    ")
                    .append(offCommands[i].getCommandName())
                    .append("\n");
        }
        stringBuilder.append("[撤销] ")
                .append(undoCommand.getClass().getSimpleName())
                .append("\n");
        return stringBuilder.toString();
    }
}